package com.elitel.ctrl;

import com.alibaba.fastjson.JSONObject;
import com.elitel.dto.Args;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

@RestController
@RequestMapping("oriApi")
public class BaseCtrl {
    @Resource
    RestTemplate restTemplate;

    @PostMapping("test")
    public Object test(@RequestBody Args args) {
        String method = args.getMethod().toUpperCase();
        switch (method) {
            case "GET":
                return doGet(args);
            case "POST":
                String contentType = args.getContentType();
                if (contentType == null) {
                    return ResponseEntity.badRequest().body("Content-Type is required for POST requests");
                }
                contentType = contentType.toLowerCase();

                if (contentType.contains("application/json")) {
                    return doPostJson(args);
                } else if (contentType.contains("multipart/form-data")) {
                    return doPostFormData(args);
                } else if (contentType.contains("application/x-www-form-urlencoded")) {
                    return doPostXwwwFormUrlencoded(args);
                } else if (contentType.contains("text/plain")) {
                    return doPostTextPlain(args);
                } else if (contentType.contains("text/xml") || contentType.contains("application/xml")) {
                    return doPostXml(args);
                }
            default:
                return ResponseEntity.badRequest().body("Unsupported HTTP method: " + method);
        }
    }

    // application/json 请求
    public ResponseEntity<Object> doPostJson(Args args) {
        HttpHeaders headers = buildHeaders(args);
        headers.setContentType(MediaType.APPLICATION_JSON);

        HttpEntity<Object> requestEntity = new HttpEntity<>(args.getBody(), headers);
        ResponseEntity<Object> objectResponseEntity = executeRequest(args.getUrl(), HttpMethod.POST, requestEntity);
        return objectResponseEntity;
    }

    // multipart/form-data 请求
    public ResponseEntity<Object> doPostFormData(Args args) {
        HttpHeaders headers = buildHeaders(args);
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
        if (args.getBody() != null) {
            args.getBody().forEach(body::add);
        }

        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
        return executeRequest(args.getUrl(), HttpMethod.POST, requestEntity);
    }

    // application/x-www-form-urlencoded 请求
    public ResponseEntity<Object> doPostXwwwFormUrlencoded(Args args) {
        HttpHeaders headers = buildHeaders(args);
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
        if (args.getBody() != null) {
            args.getBody().forEach((key, value) -> body.add(key, Objects.toString(value)));
        }

        HttpEntity<MultiValueMap<String, String>> requestEntity = new HttpEntity<>(body, headers);
        return executeRequest(args.getUrl(), HttpMethod.POST, requestEntity);
    }

    // text/plain 请求
    public ResponseEntity<Object> doPostTextPlain(Args args) {
        HttpHeaders headers = buildHeaders(args);
        headers.setContentType(MediaType.TEXT_PLAIN);

        String textBody = args.getBody() != null ? args.getBody().getString("data") : "";
        HttpEntity<String> requestEntity = new HttpEntity<>(textBody, headers);
        return executeRequest(args.getUrl(), HttpMethod.POST, requestEntity);
    }

    // XML 请求 (text/xml 或 application/xml)
    public ResponseEntity<Object> doPostXml(Args args) {
        HttpHeaders headers = buildHeaders(args);
        MediaType mediaType = args.getContentType().contains("text/xml") ?
                MediaType.TEXT_XML : MediaType.APPLICATION_XML;
        headers.setContentType(mediaType);

        String xmlBody = args.getBody() != null ? args.getBody().getString("data") : "";
        HttpEntity<String> requestEntity = new HttpEntity<>(xmlBody, headers);
        return executeRequest(args.getUrl(), HttpMethod.POST, requestEntity);
    }


    // GET 请求
    public ResponseEntity<Object> doGet(Args args) {
        HttpHeaders headers = buildHeaders(args);

        String url = args.getUrl() ;
        if (args.getBody() != null) {

            JSONObject body = args.getBody();
            Set<Map.Entry<String, Object>> entries = body.entrySet();
            StringBuilder tmp= new StringBuilder();
            for (Map.Entry<String, Object> entry : entries) {
                String key = entry.getKey();
                Object value = entry.getValue();
                tmp.append("&").append(key).append("=").append(value);
            }
            if (tmp.length() > 0) {
                url = url + "?" + tmp.substring(1);
            }
        }

        HttpEntity<?> requestEntity = new HttpEntity<>(headers);
        ResponseEntity<Object> objectResponseEntity = executeRequest(url, HttpMethod.GET, requestEntity);
        return objectResponseEntity;
    }


    // 辅助方法：构建请求头
    private HttpHeaders buildHeaders(Args args) {
        HttpHeaders headers = new HttpHeaders();
        if (args.getHeaders() != null) {
            args.getHeaders().forEach((key, value) -> headers.add(key, value.toString()));
        }
        return headers;
    }

    // 辅助方法：执行请求
    private ResponseEntity<Object> executeRequest(String url, HttpMethod method, HttpEntity<?> requestEntity) {
        try {
            return restTemplate.exchange(url, method, requestEntity, Object.class);
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("Request failed: " + e.getMessage());
        }
    }


    // 辅助方法：确定媒体类型
    private MediaType determineMediaType(String contentType) {
        if (contentType == null) return null;

        contentType = contentType.toLowerCase();
        if (contentType.contains("application/json")) {
            return MediaType.APPLICATION_JSON;
        } else if (contentType.contains("multipart/form-data")) {
            return MediaType.MULTIPART_FORM_DATA;
        } else if (contentType.contains("application/x-www-form-urlencoded")) {
            return MediaType.APPLICATION_FORM_URLENCODED;
        } else if (contentType.contains("text/plain")) {
            return MediaType.TEXT_PLAIN;
        } else if (contentType.contains("text/xml")) {
            return MediaType.TEXT_XML;
        } else if (contentType.contains("application/xml")) {
            return MediaType.APPLICATION_XML;
        } else if (contentType.contains("application/octet-stream")) {
            return MediaType.APPLICATION_OCTET_STREAM;
        } else {
            try {
                return MediaType.parseMediaType(contentType);
            } catch (Exception e) {
                return null;
            }
        }
    }
}